package com.bbs.toutiao.aspect;

import cn.hutool.core.date.DateUtil;
import com.bbs.toutiao.entity.LogsEntity;
import com.bbs.toutiao.service.admin.impl.LogSysServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

/**
 * 描述: 日志AOP捕获
 * 作者： zhangBin
 * 时间： 2024/3/4 21:21
 * 版本： 1.0
 */

@Aspect
@Component
@Slf4j
public class LoggingAspect {

    @Resource
    LogSysServiceImpl logSysService;

    @Resource
    private HttpServletRequest request;

    //切面
    @Pointcut("@annotation(com.bbs.toutiao.aspect.SysLog)")
    public void loggerOutPointcut() {

    }

    @Around("loggerOutPointcut()")
    public Object saveLog(ProceedingJoinPoint joinPoint) throws Throwable{
        Object result;
        LogsEntity logs = new LogsEntity();
        // 获取请求ip
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null) {
            ip = request.getRemoteAddr();
        } else {
            // X-Forwarded-For头部可以包含多个IP地址，第一个地址通常是客户端的真实IP地址
            ip = ip.split(",")[0];
        }
        logs.setLogIp(ip);
        logs.setLogContent(request.getRequestURL().toString());
        logs.setLogUserAgent(request.getHeader("User-Agent"));


        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取方法
        Method method = signature.getMethod();
        // 获取方法上的SysLog注解
        SysLog sysLog = method.getAnnotation(SysLog.class);
        //获取指定方法的类名
        String methodName=  joinPoint.getSignature().getName();
//        log.info("sysLog：{}===methodName:{}",sysLog.value(),methodName);
        if(methodName.equals("addArticle")){
            logs.setLogParam("信息过长无法统计");
        }else{
            logs.setLogParam(Arrays.toString(joinPoint.getArgs()));
        }

        // 获取注解中的值
        String  value = sysLog.value();
        try {
            // 调用目标方法
            result = joinPoint.proceed();
            logs.setLogStatus("SUCCESS");
            logs.setLogMessage("执行了"+methodName+"方法"+value+",执行成功");
        } catch (Exception e) {
            // 如果目标方法执行失败，我们认为这个操作是失败的
            logs.setLogStatus("FAILURE");
            // 记录异常信息
            logs.setLogMessage("执行了"+methodName+"方法"+value+",执行失败原因为:"+e.getMessage());
            throw e;  // 将异常抛出，以便外部处理
        } finally {
            // 获取当前时间
            Date now = DateUtil.date();
            // 按照指定格式对日期进行格式化为字符串，这里yyyy-MM-dd HH:mm:ss.SSS代表年-月-日 时:分:秒.毫秒
            String format = DateUtil.format(now, "yyyy-MM-dd HH:mm:ss.SSS");
            logs.setLogTime(format);

            // 保存日志记录
           int i = logSysService.logSave(logs);
           log.info("sysLog：{}===i:{}",sysLog.value(),i);
        }

        return result;
    }
}
